பைத்தானின் ஹைப்போதெசிஸ் நூலகத்துடன் சொத்து அடிப்படையிலான சோதனையைக் கண்டறியவும். விளிம்புநிலை வழக்குகளைக் கண்டறிந்து மேலும் வலுவான, நம்பகமான மென்பொருளை உருவாக்க எடுத்துக்காட்டு அடிப்படையிலான சோதனைகளுக்கு அப்பால் செல்லவும்.
யூனிட் சோதனைகளுக்கு அப்பால்: பைத்தானின் ஹைப்போதெசிஸுடன் சொத்து அடிப்படையிலான சோதனையைப் பற்றிய ஆழமான ஆய்வு
மென்பொருள் வளர்ச்சியின் உலகில், தரம் என்பது சோதனையின் அடிப்படையாகும். பல தசாப்தங்களாக, ஆதிக்கம் செலுத்தும் முன்னுதாரணம் எடுத்துக்காட்டு அடிப்படையிலான சோதனை ஆகும். உள்ளீடுகளை கவனமாக உருவாக்குகிறோம், எதிர்பார்க்கப்படும் வெளியீடுகளை வரையறுக்கிறோம், மேலும் எங்கள் குறியீடு திட்டமிட்டபடி செயல்படுகிறதா என்பதைச் சரிபார்க்க கூற்றுகளை எழுதுகிறோம். unittest
மற்றும் pytest
போன்ற கட்டமைப்புகளில் காணப்படும் இந்த அணுகுமுறை சக்திவாய்ந்த மற்றும் இன்றியமையாதது. ஆனால் நீங்கள் எப்போதாவது பார்க்க நினைத்திராத பிழைகளைக் கண்டறியக்கூடிய ஒரு நிரப்பு அணுகுமுறை இருக்கிறது என்று நான் சொன்னால் என்ன செய்வது?
சொத்து அடிப்படையிலான சோதனையின் உலகில் வரவேற்கிறோம், இந்த முன்னுதாரணம் உங்கள் குறியீட்டின் பொதுவான பண்புகளை சரிபார்ப்பதற்கு குறிப்பிட்ட எடுத்துக்காட்டுகளை சோதிப்பதிலிருந்து கவனத்தை மாற்றுகிறது. பைத்தான் சூழலில், இந்த அணுகுமுறையின் மறுக்கமுடியாத சாம்பியன் ஹைப்போதெசிஸ் எனப்படும் ஒரு நூலகம் ஆகும்.
இந்த விரிவான வழிகாட்டி, ஒரு முழுமையான ஆரம்பநிலை முதல் ஹைப்போதெசிஸுடன் சொத்து அடிப்படையிலான சோதனையின் நம்பிக்கையான பயிற்சியாளர் வரை உங்களை அழைத்துச் செல்லும். முக்கிய கருத்துகளை ஆராய்வோம், நடைமுறை எடுத்துக்காட்டுகளில் மூழ்கி, மேலும் வலுவான, நம்பகமான மற்றும் பிழை-எதிர்ப்பு மென்பொருளை உருவாக்க இந்த சக்திவாய்ந்த கருவியை உங்கள் அன்றாட வளர்ச்சி பணிப்பாய்வில் எவ்வாறு ஒருங்கிணைப்பது என்பதை அறிந்து கொள்வோம்.
சொத்து அடிப்படையிலான சோதனை என்றால் என்ன? ஒரு மனநிலை மாற்றம்
ஹைப்போதெசிஸைப் புரிந்து கொள்ள, முதலில் சொத்து அடிப்படையிலான சோதனையின் அடிப்படை யோசனையைப் புரிந்து கொள்ள வேண்டும். நாம் அனைவரும் அறிந்த பாரம்பரிய எடுத்துக்காட்டு அடிப்படையிலான சோதனையுடன் ஒப்பிடுவோம்.
எடுத்துக்காட்டு அடிப்படையிலான சோதனை: பழக்கமான பாதை
நீங்கள் ஒரு தனிப்பயன் வரிசையாக்கச் செயல்பாட்டை எழுதியுள்ளீர்கள் என்று கற்பனை செய்து பாருங்கள், my_sort()
. எடுத்துக்காட்டு அடிப்படையிலான சோதனையுடன், உங்கள் சிந்தனை செயல்முறை இதுவாக இருக்கும்:
- "ஒரு எளிய, வரிசைப்படுத்தப்பட்ட பட்டியலுடன் இதைச் சோதிப்போம்." ->
assert my_sort([1, 2, 3]) == [1, 2, 3]
- "தலைகீழ் வரிசையில் பட்டியலைப் பற்றி என்ன சொல்வது?" ->
assert my_sort([3, 2, 1]) == [1, 2, 3]
- "வெற்று பட்டியலைப் பற்றி எப்படி?" ->
assert my_sort([]) == []
- "நகல்களைக் கொண்ட பட்டியல்?" ->
assert my_sort([5, 1, 5, 2]) == [1, 2, 5, 5]
- "எதிர்மறை எண்களுடன் கூடிய பட்டியல்?" ->
assert my_sort([-1, -5, 0]) == [-5, -1, 0]
இது பயனுள்ளது, ஆனால் இது ஒரு அடிப்படை வரம்பைக் கொண்டுள்ளது: நீங்கள் நினைக்கக்கூடிய வழக்குகளை மட்டுமே சோதிக்கிறீர்கள். உங்கள் சோதனைகள் உங்கள் கற்பனைக்கு ஏற்றது. மிக பெரிய எண்கள், மிதக்கும் புள்ளி குறைபாடுகள், குறிப்பிட்ட யுனிகோடு எழுத்துகள் அல்லது எதிர்பாராத நடத்தையை ஏற்படுத்தும் தரவுகளின் சிக்கலான சேர்க்கைகள் தொடர்பான விளிம்புநிலை வழக்குகளை நீங்கள் தவறவிடக்கூடும்.
சொத்து அடிப்படையிலான சோதனை: மாறிலிகளில் சிந்திப்பது
சொத்து அடிப்படையிலான சோதனை ஸ்கிரிப்டை மாற்றுகிறது. குறிப்பிட்ட எடுத்துக்காட்டுகளை வழங்குவதற்குப் பதிலாக, உங்கள் செயல்பாட்டின் பண்புகளை, அல்லது மாறிலிகள், அதாவது எந்தவொரு சரியான உள்ளீட்டிற்கும் உண்மையாக இருக்க வேண்டிய விதிகளை நீங்கள் வரையறுக்கிறீர்கள். எங்கள் my_sort()
செயல்பாட்டிற்கு, இந்த பண்புகள் இருக்கலாம்:
- வெளியீடு வரிசைப்படுத்தப்பட்டது: எந்தவொரு எண்களின் பட்டியலுக்கும், வெளியீட்டு பட்டியலில் உள்ள ஒவ்வொரு உறுப்பும் அதைத் தொடர்வதை விட குறைவாகவோ அல்லது சமமாகவோ இருக்கும்.
- வெளியீட்டில் உள்ளீட்டில் உள்ள அதே கூறுகள் உள்ளன: வரிசைப்படுத்தப்பட்ட பட்டியல் என்பது அசல் பட்டியலின் ஒரு இடமாற்றம்; எந்த கூறுகளும் சேர்க்கப்படவில்லை அல்லது இழக்கப்படவில்லை.
- செயல்பாடு நிலையானது: ஏற்கனவே வரிசைப்படுத்தப்பட்ட பட்டியலை வரிசைப்படுத்துவது அதை மாற்றக்கூடாது. அதாவது,
my_sort(my_sort(some_list)) == my_sort(some_list)
.
இந்த அணுகுமுறையுடன், நீங்கள் சோதனை தரவை எழுதுவதில்லை. நீங்கள் விதிகளை எழுதுகிறீர்கள். பின்னர் நீங்கள் ஹைப்போதெசிஸ் போன்ற ஒரு கட்டமைப்பை அனுமதித்து, உங்கள் பண்புகளை தவறாக நிரூபிக்க முயற்சிப்பதற்காக நூற்றுக்கணக்கான அல்லது ஆயிரக்கணக்கான சீரற்ற, மாறுபட்ட மற்றும் பெரும்பாலும் வஞ்சக உள்ளீடுகளை உருவாக்குகிறது. அது ஒரு சொத்தை உடைக்கும் ஒரு உள்ளீட்டைக் கண்டால், அது ஒரு பிழையைக் கண்டுபிடித்தது.
ஹைப்போதெசிஸை அறிமுகப்படுத்துகிறோம்: உங்கள் தானியங்கி சோதனை தரவு ஜெனரேட்டர்
ஹைப்போதெசிஸ் என்பது பைத்தானுக்கான சிறந்த சொத்து அடிப்படையிலான சோதனை நூலகமாகும். நீங்கள் வரையறுக்கும் பண்புகளை எடுத்து அவற்றை சவால் செய்வதற்கான சோதனை தரவை உருவாக்குவதற்கான கடின உழைப்பைச் செய்கிறது. இது ஒரு சீரற்ற தரவு ஜெனரேட்டர் மட்டுமல்ல; பிழைகளை திறம்படக் கண்டறிய வடிவமைக்கப்பட்ட ஒரு அறிவார்ந்த மற்றும் சக்திவாய்ந்த கருவி இது.
ஹைப்போதெசிஸின் முக்கிய அம்சங்கள்
- தானியங்கி சோதனை கேஸ் உருவாக்கம்: உங்களுக்குத் தேவையான தரவின் *வடிவத்தை* (எ.கா., "ஒரு முழு எண்களின் பட்டியல்," "எழுத்துக்களை மட்டுமே கொண்ட ஒரு சரம்," "எதிர்காலத்தில் ஒரு தேதிநேரம்") நீங்கள் வரையறுக்கிறீர்கள், மேலும் ஹைப்போதெசிஸ் அந்த வடிவத்திற்கு இணங்க பல்வேறு எடுத்துக்காட்டுகளை உருவாக்குகிறது.
- அறிவார்ந்த சுருக்கம்: இது மந்திர அம்சம். ஹைப்போதெசிஸ் ஒரு தோல்வியுற்ற சோதனை வழக்கைக் கண்டறிந்தால் (எ.கா., உங்கள் வரிசைப்படுத்தும் செயல்பாட்டை செயலிழக்கச் செய்யும் 50 சிக்கலான எண்களின் பட்டியல்), அது அந்த பெரிய பட்டியலை மட்டும் அறிக்கையிடாது. தோல்வியை இன்னும் ஏற்படுத்தும் மிகச்சிறிய உதாரணத்தைக் கண்டறிய உள்ளீட்டை அறிவார்ந்ததாகவும் தானாகவும் எளிதாக்குகிறது. 50-உறுப்பு பட்டியலுக்குப் பதிலாக, தோல்வி
[inf, nan]
உடன் நிகழ்கிறது என்று அது தெரிவிக்கலாம். இது பிழைத்திருத்தத்தை நம்பமுடியாத அளவிற்கு வேகமாகவும் திறமையாகவும் ஆக்குகிறது. - தடையற்ற ஒருங்கிணைப்பு: ஹைப்போதெசிஸ்
pytest
மற்றும்unittest
போன்ற பிரபலமான சோதனை கட்டமைப்புகளுடன் சரியான முறையில் ஒருங்கிணைக்கிறது. உங்கள் பணிப்பாய்வை மாற்றாமல், உங்கள் தற்போதைய எடுத்துக்காட்டு அடிப்படையிலான சோதனைகளுடன் சொத்து அடிப்படையிலான சோதனைகளைச் சேர்க்கலாம். - உத்திகளின் பணக்கார நூலகம்: எளிய முழு எண்கள் மற்றும் சரங்கள் முதல் சிக்கலான, கூடு கட்டப்பட்ட தரவு கட்டமைப்புகள், நேர மண்டல விழிப்புணர்வு தேதிகள் மற்றும் நேரங்கள் மற்றும் NumPy வரிசைகள் வரை அனைத்தையும் உருவாக்குவதற்கான உள்ளமைக்கப்பட்ட "உத்திகளின்" ஒரு பெரிய தொகுப்புடன் இது வருகிறது.
- மாநில சோதனை: மிகவும் சிக்கலான அமைப்புகளுக்கு, ஹைப்போதெசிஸ் மாநில மாற்றங்களில் பிழைகளைக் கண்டறியும் நடவடிக்கைகளின் வரிசையை சோதிக்க முடியும், இது எடுத்துக்காட்டு அடிப்படையிலான சோதனையுடன் பிரபலமற்றது.
தொடங்குதல்: உங்கள் முதல் ஹைப்போதெசிஸ் சோதனை
நம் கைகளை அழுக்காக்குவோம். ஹைப்போதெசிஸைப் புரிந்து கொள்ள சிறந்த வழி அதை செயலில் பார்ப்பது.
நிறுவல்
முதலில், நீங்கள் ஹைப்போதெசிஸையும், உங்கள் விருப்பமான சோதனை ரன்னரையும் நிறுவ வேண்டும் (நாங்கள் pytest
பயன்படுத்துவோம்). இது மிகவும் எளிது:
pip install pytest hypothesis
ஒரு எளிய எடுத்துக்காட்டு: ஒரு முழுமையான மதிப்பு செயல்பாடு
ஒரு எண்ணின் முழுமையான மதிப்பைக் கணக்கிட வேண்டிய ஒரு எளிய செயல்பாட்டைப் பார்ப்போம். சற்று குறைபாடுள்ள செயலாக்கம் இதுபோல் இருக்கலாம்:
# `my_math.py` என பெயரிடப்பட்ட ஒரு கோப்பில் def custom_abs(x): """முழுமையான மதிப்பு செயல்பாட்டின் தனிப்பயன் செயலாக்கம்.""" if x < 0: return -x return x
இப்போது, ஒரு சோதனை கோப்பை எழுதுவோம், test_my_math.py
. முதலில், பாரம்பரிய pytest
அணுகுமுறை:
# test_my_math.py (எடுத்துக்காட்டு அடிப்படையிலானது) def test_abs_positive(): assert custom_abs(5) == 5 def test_abs_negative(): assert custom_abs(-5) == 5 def test_abs_zero(): assert custom_abs(0) == 0
இந்த சோதனைகள் கடந்து செல்கின்றன. இந்த எடுத்துக்காட்டுகளை அடிப்படையாகக் கொண்டு எங்கள் செயல்பாடு சரியாகத் தெரிகிறது. ஆனால் இப்போது, ஹைப்போதெசிஸுடன் ஒரு சொத்து அடிப்படையிலான சோதனையை எழுதுவோம். முழுமையான மதிப்பு செயல்பாட்டின் முக்கிய சொத்து என்ன? முடிவு ஒருபோதும் எதிர்மறையாக இருக்கக்கூடாது.
# test_my_math.py (ஹைப்போதெசிஸுடன் சொத்து அடிப்படையிலானது) from hypothesis import given from hypothesis import strategies as st from my_math import custom_abs @given(st.integers()) def test_abs_property_is_non_negative(x): """சொத்து: எந்தவொரு முழு எண்ணின் முழுமையான மதிப்பும் எப்போதும் >= 0.""" assert custom_abs(x) >= 0
இதை உடைப்போம்:
from hypothesis import given, strategies as st
: தேவையான கூறுகளை இறக்குமதி செய்கிறோம்.given
என்பது ஒரு வழக்கமான சோதனை செயல்பாட்டை சொத்து அடிப்படையிலான சோதனையாக மாற்றும் ஒரு அலங்கரிப்பு.strategies
என்பது தரவு ஜெனரேட்டர்களைக் கண்டுபிடிக்கும் தொகுதி.@given(st.integers())
: இது சோதனையின் மையமாகும்.@given
அலங்கரிப்பாளர் இந்த சோதனை செயல்பாட்டை பல முறை இயக்க ஹைப்போதெசிஸிடம் கூறுகிறார். ஒவ்வொரு ரன்னிலும், அது வழங்கப்பட்ட உத்தியைப் பயன்படுத்தி ஒரு மதிப்பை உருவாக்கும்,st.integers()
, மேலும் அதை எங்கள் சோதனை செயல்பாட்டிற்கு வாதமாக வழங்கும்x
.assert custom_abs(x) >= 0
: இதுவே நம் சொத்து. ஹைப்போதெசிஸ் என்ன முழு எண்ணை விரும்பினாலும், எங்கள் செயல்பாட்டின் முடிவு பூஜ்யத்தை விட அதிகமாகவோ அல்லது சமமாகவோ இருக்க வேண்டும் என்று நாங்கள் வலியுறுத்துகிறோம்.
நீங்கள் இதை pytest
உடன் இயக்கும்போது, இது பல மதிப்புகளுக்கு கடந்து செல்லும். ஹைப்போதெசிஸ் 0, -1, 1, பெரிய நேர்மறை எண்கள், பெரிய எதிர்மறை எண்கள் மற்றும் பலவற்றை முயற்சிக்கும். எங்கள் எளிய செயல்பாடு இவை அனைத்தையும் சரியாகக் கையாளுகிறது. இப்போது, ஒரு பலவீனத்தைக் கண்டுபிடிக்க முடியுமா என்று பார்க்க வேறு ஒரு உத்தியை முயற்சிப்போம்.
# மிதக்கும் புள்ளி எண்களுடன் சோதிப்போம் @given(st.floats()) def test_abs_floats_property(x): assert custom_abs(x) >= 0
நீங்கள் இதை இயக்கினால், ஹைப்போதெசிஸ் விரைவில் தோல்வியுற்ற ஒரு வழக்கைக் கண்டுபிடிக்கும்!
தவறான எடுத்துக்காட்டு: test_abs_floats_property(x=nan) ... assert custom_abs(nan) >= 0 AssertionError: assert nan >= 0
எங்கள் செயல்பாடு, float('nan')
(எண் இல்லை) வழங்கப்பட்டால், nan
ஐ வழங்குகிறது என்பதைக் கண்டறிந்தது. கூற்று nan >= 0
தவறானது. நாம் கையேடாக சோதிக்க நினைத்திராத ஒரு நுட்பமான பிழையை நாம் இப்போது கண்டுபிடித்துள்ளோம். இதைச் சமாளிக்க எங்கள் செயல்பாட்டை சரிசெய்ய முடியும், ஒரு ValueError
ஐ உயர்த்துவதன் மூலம் அல்லது ஒரு குறிப்பிட்ட மதிப்பை வழங்குவதன் மூலம்.
இன்னும் சிறந்தது, பிழை மிகவும் குறிப்பிட்ட மிதவையுடன் இருந்தால் என்ன செய்வது? ஹைப்போதெசிஸின் சுருக்கி, தோல்வியுற்ற ஒரு பெரிய, சிக்கலான எண்ணை எடுத்து, பிழையைத் தூண்டும் எளிமையான பதிப்பிற்கு குறைக்கும்.
உத்திகளின் சக்தி: உங்கள் சோதனை தரவை உருவாக்குதல்
உத்திகள் ஹைப்போதெசிஸின் இதயம். அவை தரவை உருவாக்குவதற்கான சமையல் குறிப்புகள். நூலகத்தில் ஏராளமான உள்ளமைக்கப்பட்ட உத்திகள் உள்ளன, மேலும் நீங்கள் கற்பனை செய்யக்கூடிய எந்த தரவு கட்டமைப்பையும் உருவாக்க அவற்றை இணைத்து தனிப்பயனாக்கலாம்.
பொதுவான உள்ளமைக்கப்பட்ட உத்திகள்
- எண்:
st.integers(min_value=0, max_value=1000)
: முழு எண்களை உருவாக்குகிறது, விருப்பமாக ஒரு குறிப்பிட்ட வரம்பிற்குள்.st.floats(min_value=0.0, max_value=1.0, allow_nan=False, allow_infinity=False)
: மிதவைகளை உருவாக்குகிறது, சிறப்பு மதிப்புகள் மீது சிறந்த கட்டுப்பாட்டுடன்.st.fractions()
,st.decimals()
- உரை:
st.text(min_size=1, max_size=50)
: ஒரு குறிப்பிட்ட நீளத்தின் யுனிகோடு சரங்களை உருவாக்குகிறது.st.text(alphabet='abcdef0123456789')
: ஒரு குறிப்பிட்ட எழுத்து தொகுப்பிலிருந்து சரங்களை உருவாக்குகிறது (எ.கா., ஹெக்ஸ் குறியீடுகளுக்கு).st.characters()
: தனிப்பட்ட எழுத்துக்களை உருவாக்குகிறது.
- சேகரிப்புகள்:
st.lists(st.integers(), min_size=1)
: ஒவ்வொரு உறுப்பும் ஒரு முழு எண்ணாக இருக்கும் பட்டியல்களை உருவாக்குகிறது. இன்னொரு உத்தியை வாதமாக எவ்வாறு அனுப்புகிறோம் என்பதைக் கவனியுங்கள்! இது கலவை என்று அழைக்கப்படுகிறது.st.tuples(st.text(), st.booleans())
: ஒரு நிலையான கட்டமைப்பைக் கொண்ட டியூப்பிள்களை உருவாக்குகிறது.st.sets(st.integers())
st.dictionaries(keys=st.text(), values=st.integers())
: குறிப்பிட்ட முக்கிய மற்றும் மதிப்பு வகைகளுடன் அகராதிகளை உருவாக்குகிறது.
- தற்காலிக:
st.dates()
,st.times()
,st.datetimes()
,st.timedeltas()
. இவை நேர மண்டல விழிப்புணர்வு செய்யப்படலாம்.
- பலவகை:
st.booleans()
:True
அல்லதுFalse
ஐ உருவாக்குகிறது.st.just('constant_value')
: எப்போதும் ஒரே மதிப்பை உருவாக்குகிறது. சிக்கலான உத்திகளை உருவாக்குவதற்குப் பயனுள்ளது.st.one_of(st.integers(), st.text())
: வழங்கப்பட்ட உத்திகளில் இருந்து ஒரு மதிப்பை உருவாக்குகிறது.st.none()
:None
மட்டுமே உருவாக்குகிறது.
உத்திகளை இணைத்தல் மற்றும் மாற்றுதல்
ஹைப்போதெசிஸின் உண்மையான சக்தி, எளிய உத்திகளிலிருந்து சிக்கலான உத்திகளைக் கட்டும் திறனிலிருந்து வருகிறது.
.map()
ஐப் பயன்படுத்துதல்
.map()
முறை ஒரு உத்தியிலிருந்து ஒரு மதிப்பை எடுத்து அதை வேறொன்றாக மாற்ற உங்களை அனுமதிக்கிறது. உங்கள் தனிப்பயன் வகுப்புகளின் பொருட்களை உருவாக்குவதற்கு இது சரியானது.
# ஒரு எளிய தரவு வகுப்பு from dataclasses import dataclass @dataclass class User: user_id: int username: str # பயனர் பொருட்களை உருவாக்க ஒரு உத்தி user_strategy = st.builds( User, user_id=st.integers(min_value=1), username=st.text(min_size=3, alphabet='abcdefghijklmnopqrstuvwxyz') ) @given(user=user_strategy) def test_user_creation(user): assert isinstance(user, User) assert user.user_id > 0 assert user.username.isalpha()
.filter()
மற்றும் assume()
ஐப் பயன்படுத்துதல்
சில நேரங்களில் நீங்கள் சில உருவாக்கப்பட்ட மதிப்புகளை நிராகரிக்க வேண்டும். எடுத்துக்காட்டாக, தொகை பூஜ்ஜியமாக இல்லாத முழு எண்களின் பட்டியல் உங்களுக்குத் தேவைப்படலாம். நீங்கள் .filter()
பயன்படுத்தலாம்:
st.lists(st.integers()).filter(lambda x: sum(x) != 0)
இருப்பினும், .filter()
ஐப் பயன்படுத்துவது திறமையற்றதாக இருக்கும். நிபந்தனை அடிக்கடி தவறாக இருந்தால், ஒரு சரியான உதாரணத்தை உருவாக்க ஹைப்போதெசிஸ் நீண்ட நேரம் செலவிடக்கூடும். ஒரு சிறந்த அணுகுமுறை பெரும்பாலும் உங்கள் சோதனை செயல்பாட்டிற்குள் assume()
பயன்படுத்துவதாகும்:
from hypothesis import assume @given(st.lists(st.integers())) def test_something_with_non_zero_sum_list(numbers): assume(sum(numbers) != 0) # ... உங்கள் சோதனை தர்க்கம் இங்கே ...
assume()
ஹைப்போதெசிஸிடம் கூறுகிறது: "இந்த நிபந்தனை பூர்த்தி செய்யப்படாவிட்டால், இந்த உதாரணத்தை நிராகரித்துவிட்டு, புதிய ஒன்றை முயற்சி செய்யுங்கள்." இது உங்கள் சோதனை தரவைக் கட்டுப்படுத்த ஒரு நேரடியான மற்றும் பெரும்பாலும் அதிக செயல்திறன் மிக்க வழியாகும்.
st.composite()
ஐப் பயன்படுத்துதல்
உண்மையிலேயே சிக்கலான தரவு தலைமுறைக்கு ஒரு உருவாக்கப்பட்ட மதிப்பு மற்றொன்றைப் பொறுத்தது, st.composite()
உங்களுக்குத் தேவையான கருவியாகும். இது ஒரு செயல்பாட்டை ஒரு சிறப்பு draw
செயல்பாட்டை ஒரு வாதமாக எடுத்துக்கொள்ள உங்களை அனுமதிக்கிறது, இதை நீங்கள் மற்ற உத்திகளிலிருந்து மதிப்புகளை படிப்படியாகப் பெற பயன்படுத்தலாம்.
ஒரு கிளாசிக் எடுத்துக்காட்டு ஒரு பட்டியலையும், அந்த பட்டியலில் ஒரு சரியான குறியீட்டையும் உருவாக்குகிறது.
@st.composite def list_and_index(draw): # முதலில், ஒரு காலியாக இல்லாத பட்டியலை வரையவும் my_list = draw(st.lists(st.integers(), min_size=1)) # பின்னர், அந்த பட்டியலுக்கு உத்தரவாதம் அளிக்கப்படும் ஒரு குறியீட்டை வரையவும் index = draw(st.integers(min_value=0, max_value=len(my_list) - 1)) return (my_list, index) @given(data=list_and_index()) def test_list_access(data): my_list, index = data # இந்த அணுகல் நாம் உத்தியைக் கட்டிய விதத்தின் காரணமாக பாதுகாப்பாக உள்ளது element = my_list[index] assert element is not None # ஒரு எளிய கூற்று
ஹைப்போதெசிஸ் செயலில்: நிஜ-உலக காட்சிகள்
மென்பொருள் உருவாக்குநர்கள் தினமும் எதிர்கொள்ளும் யதார்த்தமான சிக்கல்களுக்கு இந்த கருத்துக்களைப் பயன்படுத்துவோம்.
நிலை 1: தரவு வரிசைப்படுத்தும் செயல்பாட்டை சோதித்தல்
ஒரு பயனர் சுயவிவரத்தை (ஒரு அகராதி) ஒரு URL-பாதுகாப்பான சரமாக வரிசைப்படுத்தும் ஒரு செயல்பாடு மற்றும் அதைத் தேடும் மற்றொரு செயல்பாடு இருப்பதாகக் கற்பனை செய்து பாருங்கள். ஒரு முக்கிய சொத்து என்னவென்றால், செயல்முறை முற்றிலும் தலைகீழாக இருக்க வேண்டும்.
import json import base64 def serialize_profile(data: dict) -> str: """ஒரு அகராதியை URL-பாதுகாப்பான base64 சரத்திற்கு வரிசைப்படுத்துகிறது.""" json_string = json.dumps(data) return base64.urlsafe_b64encode(json_string.encode('utf-8')).decode('utf-8') def deserialize_profile(encoded_str: str) -> dict: """ஒரு சரத்தை மீண்டும் ஒரு அகராதியாக மாற்றுகிறது.""" json_string = base64.urlsafe_b64decode(encoded_str.encode('utf-8')).decode('utf-8') return json.loads(json_string) # இப்போது சோதனைக்கு # JSON-இணக்கமான அகராதிகளை உருவாக்கும் ஒரு உத்தி நமக்கு வேண்டும் json_dictionaries = st.dictionaries( keys=st.text(), values=st.recursive(st.none() | st.booleans() | st.floats(allow_nan=False) | st.text(), lambda children: st.lists(children) | st.dictionaries(st.text(), children), max_leaves=10) ) @given(profile=json_dictionaries) def test_serialization_roundtrip(profile): """சொத்து: குறியிடப்பட்ட சுயவிவரத்தை மீண்டும் உருவாக்குவது அசல் சுயவிவரத்தை திருப்பித் தர வேண்டும்.""" encoded = serialize_profile(profile) decoded = deserialize_profile(encoded) assert profile == decoded
இந்த ஒற்றை சோதனை எங்கள் செயல்பாடுகளை தரவின் மிகப்பெரிய வகைகளுடன் தாக்கும்: வெற்று அகராதிகள், கூடு கட்டப்பட்ட பட்டியல்களுடன் கூடிய அகராதிகள், யுனிகோடு எழுத்துகளுடன் கூடிய அகராதிகள், விசித்திரமான விசைகளுடன் கூடிய அகராதிகள் மற்றும் பல. சில கையேடு எடுத்துக்காட்டுகளை எழுதுவதை விட இது மிகவும் முழுமையானது.
நிலை 2: வரிசைப்படுத்தும் அல்காரிதத்தை சோதித்தல்
எங்கள் வரிசைப்படுத்தும் உதாரணத்தை மறுபரிசீலனை செய்வோம். நாங்கள் முன்னர் வரையறுத்த பண்புகளை நீங்கள் எவ்வாறு சோதிப்பீர்கள் என்பது இங்கே.
from collections import Counter def my_buggy_sort(numbers): # ஒரு நுட்பமான பிழையை அறிமுகப்படுத்துவோம்: இது நகல்களைக் கைவிடுகிறது return sorted(list(set(numbers))) @given(st.lists(st.integers())) def test_sorting_properties(numbers): sorted_list = my_buggy_sort(numbers) # சொத்து 1: வெளியீடு வரிசைப்படுத்தப்பட்டுள்ளது for i in range(len(sorted_list) - 1): assert sorted_list[i] <= sorted_list[i+1] # சொத்து 2: கூறுகள் ஒரே மாதிரியாக இருக்கின்றன (இது பிழையை கண்டுபிடிக்கும்) assert Counter(numbers) == Counter(sorted_list) # சொத்து 3: செயல்பாடு நிலையானது assert my_buggy_sort(sorted_list) == sorted_list
நீங்கள் இந்த சோதனையை இயக்கும்போது, ஹைப்போதெசிஸ் சொத்து 2 க்கான ஒரு தோல்வியுற்ற உதாரணத்தை விரைவாகக் கண்டுபிடிக்கும், அதாவது numbers=[0, 0]
. எங்கள் செயல்பாடு [0]
ஐ வழங்குகிறது, மேலும் Counter([0, 0])
என்பது Counter([0])
க்கு சமமாக இல்லை. சுருக்கி தோல்வியுற்ற உதாரணம் முடிந்தவரை எளிமையானதாக இருப்பதை உறுதி செய்யும், இதனால் பிழையின் காரணத்தை உடனடியாகக் காணலாம்.
நிலை 3: மாநில சோதனை
நேரம் செல்ல செல்ல உள் நிலை மாறும் பொருட்களுக்கு (ஒரு தரவுத்தள இணைப்பு, ஒரு ஷாப்பிங் கார்ட் அல்லது ஒரு தற்காலிக சேமிப்பு போன்றவை), பிழைகளைக் கண்டுபிடிப்பது நம்பமுடியாத அளவிற்கு கடினமாக இருக்கும். ஒரு செயலைத் தூண்டுவதற்கு ஒரு குறிப்பிட்ட வரிசை செயல்பாடுகள் தேவைப்படலாம். ஹைப்போதெசிஸ் `RuleBasedStateMachine`ஐ சரியாக இந்த நோக்கத்திற்காக வழங்குகிறது.
நினைவகத்தில் இருக்கும் ஒரு முக்கிய மதிப்பு சேமிப்பகத்திற்கான ஒரு எளிய API ஐக் கற்பனை செய்து பாருங்கள்:
class SimpleKeyValueStore: def __init__(self): self._data = {} def set(self, key, value): self._data[key] = value def get(self, key): return self._data.get(key) def delete(self, key): if key in self._data: del self._data[key] def size(self): return len(self._data)
அதன் நடத்தையை நாம் மாதிரி செய்யலாம் மற்றும் ஒரு மாநில இயந்திரத்துடன் அதை சோதிக்கலாம்:
from hypothesis.stateful import RuleBasedStateMachine, rule, Bundle class KeyValueStoreMachine(RuleBasedStateMachine): def __init__(self): super().__init__() self.model = {} self.sut = SimpleKeyValueStore() # Bundle() விதிகளுக்கு இடையில் தரவைக் கடத்தப் பயன்படுகிறது keys = Bundle('keys') @rule(target=keys, key=st.text(), value=st.integers()) def set_key(self, key, value): self.model[key] = value self.sut.set(key, value) return key @rule(key=keys) def delete_key(self, key): del self.model[key] self.sut.delete(key) @rule(key=st.text()) def get_key(self, key): model_val = self.model.get(key) sut_val = self.sut.get(key) assert model_val == sut_val @rule() def check_size(self): assert len(self.model) == self.sut.size() # சோதனையை இயக்க, நீங்கள் இயந்திரத்திலிருந்து மற்றும் unittest.TestCase இலிருந்து துணை வகுப்பை உருவாக்குவீர்கள் # பைடெஸ்டில், நீங்கள் சோதனையை இயந்திர வகுப்புக்கு ஒதுக்கலாம் TestKeyValueStore = KeyValueStoreMachine.TestCase
ஹைப்போதெசிஸ் இப்போது சீரற்ற வரிசைகளை `set_key`, `delete_key`, `get_key` மற்றும் `check_size` செயல்பாடுகளை செயல்படுத்தும், ஒன்று தோல்வியடையும் கூற்றுகளை ஏற்படுத்தக்கூடிய ஒரு வரிசையைக் கண்டுபிடிக்க விடாமுயற்சியுடன் முயற்சிக்கும். நீக்கப்பட்ட விசையைப் பெறுவது சரியாக நடந்து கொள்கிறதா, பல தொகுப்புகள் மற்றும் நீக்குதல்களுக்குப் பிறகு அளவு நிலையானதாக உள்ளதா மற்றும் நீங்கள் கையேடாக சோதிக்க நினைக்காத பல காட்சிகளை அது சரிபார்க்கும்.
சிறந்த நடைமுறைகள் மற்றும் மேம்பட்ட குறிப்புகள்
- எடுத்துக்காட்டு தரவுத்தளம்: ஹைப்போதெசிஸ் புத்திசாலி. அது ஒரு பிழையைக் கண்டறிந்தால், தோல்வியுற்ற உதாரணத்தை ஒரு உள்ளூர் அடைவில் சேமிக்கும் (
.hypothesis/
). அடுத்த முறை உங்கள் சோதனைகளை இயக்கும்போது, அது முதலில் தோல்வியுற்ற அந்த உதாரணத்தை மீண்டும் இயக்குகிறது, பிழை இன்னும் உள்ளது என்ற உடனடி கருத்தை உங்களுக்கு வழங்குகிறது. நீங்கள் அதை சரிசெய்தவுடன், உதாரணம் மீண்டும் இயக்கப்படுவதில்லை. @settings
உடன் சோதனை செயல்படுத்தலை கட்டுப்படுத்துதல்:@settings
அலங்கரிப்பாளரைப் பயன்படுத்தி சோதனை இயங்கின் பல அம்சங்களைக் கட்டுப்படுத்தலாம். நீங்கள் எடுத்துக்காட்டுகளின் எண்ணிக்கையை அதிகரிக்கலாம், ஒரு உதாரணம் எவ்வளவு நேரம் இயங்கலாம் என்பதற்கான காலக்கெடுவை அமைக்கலாம் (முடிவிலி சுழல்களைப் பிடிக்க), மற்றும் சில சுகாதார சோதனைகளை முடக்கலாம்.@settings(max_examples=500, deadline=1000) # 500 எடுத்துக்காட்டுகளை இயக்கவும், 1-வினாடி காலக்கெடு @given(...) ...
- தோல்விகளை மீண்டும் உருவாக்குதல்: ஒவ்வொரு ஹைப்போதெசிஸ் ரன்னும் ஒரு விதை மதிப்பை அச்சிடுகிறது (எ.கா.,
@reproduce_failure('version', 'seed')
). ஒரு CI சேவையகம் உள்ளூரில் நீங்கள் மீண்டும் உருவாக்க முடியாத ஒரு பிழையைக் கண்டால், இந்த அலங்கரிப்பாளரை வழங்கப்பட்ட விதையுடன் பயன்படுத்தி ஹைப்போதெசிஸ் துல்லியமாக அதே வரிசையில் எடுத்துக்காட்டுகளை இயக்கலாம். - CI/CD உடன் ஒருங்கிணைத்தல்: ஹைப்போதெசிஸ் எந்தவொரு தொடர்ச்சியான ஒருங்கிணைப்பு குழாய்க்கும் சரியான பொருத்தம். உற்பத்திக்கு வருவதற்கு முன்பு தெளிவற்ற பிழைகளைக் கண்டறியும் திறன், இது ஒரு விலைமதிப்பற்ற பாதுகாப்பு வலையாக அமைகிறது.
மனநிலை மாற்றம்: பண்புகளில் சிந்திப்பது
ஹைப்போதெசிஸை ஏற்றுக்கொள்வது ஒரு புதிய நூலகத்தைக் கற்றுக் கொள்வதை விட அதிகம்; இது உங்கள் குறியீட்டின் சரியான தன்மை பற்றி சிந்திப்பதில் ஒரு புதிய வழியைக் கடைப்பிடிப்பதாகும். "நான் என்ன உள்ளீடுகளை சோதிக்க வேண்டும்?" என்று கேட்பதற்கு பதிலாக, நீங்கள் கேட்கத் தொடங்குகிறீர்கள், "இந்த குறியீடு பற்றிய உலகளாவிய உண்மைகள் என்ன?"
பண்புகளை அடையாளம் காண முயற்சிக்கும்போது உங்களுக்கு வழிகாட்ட சில கேள்விகள் இங்கே உள்ளன:
- ஒரு தலைகீழ் செயல்பாடு இருக்கிறதா? (எ.கா., வரிசைப்படுத்துதல்/வரிசைவிலக்கு, குறியாக்கம்/டிகோடிங், சுருக்கவும்/விரிவாக்கு). செயல்பாடு மற்றும் அதன் தலைகீழ் செயல்படுத்துவது அசல் உள்ளீட்டை அளிக்க வேண்டும் என்பதே சொத்து.
- செயல்பாடு நிலையானதா? (எ.கா.,
abs(abs(x)) == abs(x)
). செயல்பாட்டை ஒன்றுக்கு மேற்பட்ட முறை பயன்படுத்துவது அதை ஒரு முறை பயன்படுத்துவதற்கு சமமான முடிவை உருவாக்க வேண்டும். - அதே முடிவை கணக்கிட வேறு, எளிமையான வழி இருக்கிறதா? உங்கள் சிக்கலான, உகந்த செயல்பாட்டை ஒரு எளிய, வெளிப்படையாக சரியான பதிப்புடன் (எ.கா., உங்கள் ஆடம்பரமான வரிசையை பைத்தானின் உள்ளமைக்கப்பட்ட
sorted()
உடன் சோதித்தல்) அதே வெளியீட்டை உருவாக்கும் என்பதை நீங்கள் சோதிக்கலாம். - வெளியீட்டைப் பற்றி எப்போதும் என்ன உண்மை இருக்க வேண்டும்? (எ.கா., `find_prime_factors` செயல்பாட்டின் வெளியீடு முதன்மை எண்களை மட்டுமே கொண்டிருக்க வேண்டும், மேலும் அவற்றின் தயாரிப்பு உள்ளீட்டிற்கு சமமாக இருக்க வேண்டும்).
- மாநிலம் எவ்வாறு மாறுகிறது? (மாநில சோதனைக்கு) எந்தவொரு சரியான செயல்பாட்டிற்கும் பிறகு என்ன மாறிலிகள் பராமரிக்கப்பட வேண்டும்? (எ.கா., ஒரு ஷாப்பிங் கார்ட்டில் உள்ள பொருட்களின் எண்ணிக்கை ஒருபோதும் எதிர்மறையாக இருக்க முடியாது).
முடிவு: ஒரு புதிய நம்பிக்கை நிலை
ஹைப்போதெசிஸுடன் சொத்து அடிப்படையிலான சோதனை எடுத்துக்காட்டு அடிப்படையிலான சோதனையை மாற்றாது. முக்கியமான வணிக தர்க்கத்திற்கும், நன்கு புரிந்து கொள்ளப்பட்ட தேவைகளுக்கும் (எ.கா., "நாடு X ஐச் சேர்ந்த ஒரு பயனர் விலை Y ஐப் பார்க்க வேண்டும்") இன்னும் குறிப்பிட்ட, கையால் எழுதப்பட்ட சோதனைகள் உங்களுக்குத் தேவை.
ஹைப்போதெசிஸ் வழங்குவது உங்கள் குறியீட்டின் நடத்தை ஆராய்வதற்கும், எதிர்பாராத விளிம்புநிலை வழக்குகளைக் காப்பதற்கும் ஒரு சக்திவாய்ந்த, தானியங்கி வழியாகும். இது ஒரு சோர்வில்லாத கூட்டாளராக செயல்படுகிறது, ஆயிரக்கணக்கான சோதனைகளை உருவாக்குகிறது, அது எந்த மனிதனாலும் யதார்த்தமாக எழுதக்கூடியதை விட வேறுபட்டதாகவும் வஞ்சகமானதாகவும் இருக்கும். உங்கள் குறியீட்டின் அடிப்படை பண்புகளை வரையறுப்பதன் மூலம், ஹைப்போதெசிஸ் எதிராக சோதிக்கக்கூடிய ஒரு வலுவான விவரக்குறிப்பை நீங்கள் உருவாக்குகிறீர்கள், இது உங்கள் மென்பொருளில் ஒரு புதிய நம்பிக்கையை உங்களுக்கு அளிக்கிறது.
அடுத்த முறை நீங்கள் ஒரு செயல்பாட்டை எழுதும் போது, எடுத்துக்காட்டுகளுக்கு அப்பால் சிந்திக்க ஒரு கணம் எடுத்துக் கொள்ளுங்கள். உங்களை நீங்களே கேட்டுக்கொள்ளுங்கள், "விதிகள் என்ன? எப்போதும் என்ன உண்மை இருக்க வேண்டும்?" பின்னர், அவற்றை உடைக்க ஹைப்போதெசிஸை கடினமாக உழைக்க விடுங்கள். அது என்ன கண்டுபிடிக்கும் என்பதில் நீங்கள் ஆச்சரியப்படுவீர்கள், மேலும் உங்கள் குறியீடு அதற்காக சிறப்பாக இருக்கும்.